



<!doctype html>
<html lang="en" class="no-js">
  <head>
    
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      <meta http-equiv="x-ua-compatible" content="ie=edge">
      
        <meta name="description" content="Deep learning toolbox">
      
      
        <link rel="canonical" href="https://uber.github.io/ludwig/developer_guide/">
      
      
        <meta name="author" content="Piero Molino">
      
      
        <meta name="lang:clipboard.copy" content="Copy to clipboard">
      
        <meta name="lang:clipboard.copied" content="Copied to clipboard">
      
        <meta name="lang:search.language" content="en">
      
        <meta name="lang:search.pipeline.stopwords" content="True">
      
        <meta name="lang:search.pipeline.trimmer" content="True">
      
        <meta name="lang:search.result.none" content="No matching documents">
      
        <meta name="lang:search.result.one" content="1 matching document">
      
        <meta name="lang:search.result.other" content="# matching documents">
      
        <meta name="lang:search.tokenizer" content="[\s\-]+">
      
      <link rel="shortcut icon" href="../images/ludwig_logo.png">
      <meta content="mkdocs-1.0.4, mkdocs-material-3.3.0" name="generator">
    
    
      
        <title>Developer Guide - Ludwig</title>
      
    
    
      <link rel="stylesheet" href="../assets/stylesheets/application.572ca0f0.css">
      
        <link rel="stylesheet" href="../assets/stylesheets/application-palette.22915126.css">
      
      
        
        
        <meta name="theme-color" content="#757575">


      <script src="../assets/javascripts/modernizr.962652e9.js"></script>
    
    
      
        <link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700|Roboto+Mono">
        <style>body,input{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style>
      
    
    <link rel="stylesheet" href="../assets/fonts/material-icons.css">
    
    
      <link rel="stylesheet" href="../stylesheets/extra.css">
    
      <link rel="stylesheet" href="../stylesheets/monokai.css">


  </head>
  
    
    
    <body dir="ltr" data-md-color-primary="grey" data-md-color-accent="grey">
  
    <svg class="md-svg">
      <defs>
        
        
          <svg xmlns="http://www.w3.org/2000/svg" width="416" height="448"
    viewBox="0 0 416 448" id="__github">
  <path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125
        8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5
        18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75
        19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19
        18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360
        304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25
        2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8
        38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0
        37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25
        82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75
        1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75
        0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25
        30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5
        46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34
        99.5z" />
</svg>
        
      </defs>
    </svg>
    <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
    <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
    <label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
    
      <a href="#codebase-structure" tabindex="1" class="md-skip">
        Skip to content
      </a>
    
    
      <header class="md-header" data-md-component="header">
    <nav class="md-header-nav md-grid">
        <div class="md-flex">
            <div class="md-flex__cell md-flex__cell--shrink">
                <a class="md-header-nav__button md-logo"
                   href="https://uber.github.io/ludwig/" title="Ludwig">
                    <img src="../images/ludwig_logo.svg" style="height:2rem;">
                </a>
            </div>
            <div class="md-flex__cell md-flex__cell--shrink">
                <label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
            </div>
            <div class="md-flex__cell md-flex__cell--stretch">
                <div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
                    
                    <span class="md-header-nav__topic">
                    Developer Guide
                    </span>
                    
                </div>
            </div>
            <div class="md-flex__cell md-flex__cell--shrink">
                
                
                <label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
                
<div class="md-search" data-md-component="search" role="dialog">
  <label class="md-search__overlay" for="__search"></label>
  <div class="md-search__inner" role="search">
    <form class="md-search__form" name="search">
      <input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
      <label class="md-icon md-search__icon" for="__search"></label>
      <button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
        &#xE5CD;
      </button>
    </form>
    <div class="md-search__output">
      <div class="md-search__scrollwrap" data-md-scrollfix>
        <div class="md-search-result" data-md-component="result">
          <div class="md-search-result__meta">
            Type to start searching
          </div>
          <ol class="md-search-result__list"></ol>
        </div>
      </div>
    </div>
  </div>
</div>
                
                
            </div>
            
            <div class="md-flex__cell md-flex__cell--shrink">
                <div class="md-header-nav__source">
                    


  


  <a href="https://github.com/uber/ludwig/" title="Go to repository" class="md-source" data-md-source="github">
    
      <div class="md-source__icon">
        <svg viewBox="0 0 24 24" width="24" height="24">
          <use xlink:href="#__github" width="24" height="24"></use>
        </svg>
      </div>
    
    <div class="md-source__repository">
      uber/ludwig
    </div>
  </a>

                </div>
            </div>
            
        </div>
    </nav>
</header>
    
    <div class="md-container">
      
        
      
      
      <main class="md-main">
        <div class="md-main__inner md-grid" data-md-component="container">
          
            
              <div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    <nav class="md-nav md-nav--primary" data-md-level="0">
    <label class="md-nav__title md-nav__title--site" for="__drawer">
        <a class="md-nav__button md-logo" href="https://uber.github.io/ludwig/"
           title="Ludwig">
            <img src="../images/ludwig_logo.svg" style="width: 20.8rem">
        </a>
    </label>
    
    <div class="md-nav__source">
        


  


  <a href="https://github.com/uber/ludwig/" title="Go to repository" class="md-source" data-md-source="github">
    
      <div class="md-source__icon">
        <svg viewBox="0 0 24 24" width="24" height="24">
          <use xlink:href="#__github" width="24" height="24"></use>
        </svg>
      </div>
    
    <div class="md-source__repository">
      uber/ludwig
    </div>
  </a>

    </div>
    
    <ul class="md-nav__list" data-md-scrollfix>
        
        
        
        


  <li class="md-nav__item">
    <a href=".." title="About" class="md-nav__link">
      About
    </a>
  </li>

        
        
        
        


  <li class="md-nav__item">
    <a href="../getting_started/" title="Getting Started" class="md-nav__link">
      Getting Started
    </a>
  </li>

        
        
        
        


  <li class="md-nav__item">
    <a href="../examples/" title="Examples" class="md-nav__link">
      Examples
    </a>
  </li>

        
        
        
        


  <li class="md-nav__item">
    <a href="../user_guide/" title="User Guide" class="md-nav__link">
      User Guide
    </a>
  </li>

        
        
        
        

  


  <li class="md-nav__item md-nav__item--active">
    
    <input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
    
    
      <label class="md-nav__link md-nav__link--active" for="__toc">
        Developer Guide
      </label>
    
    <a href="./" title="Developer Guide" class="md-nav__link md-nav__link--active">
      Developer Guide
    </a>
    
      
<nav class="md-nav md-nav--secondary">
  
  
  
    <label class="md-nav__title" for="__toc">Table of contents</label>
    <ul class="md-nav__list" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#codebase-structure" title="Codebase Structure" class="md-nav__link">
    Codebase Structure
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#adding-an-encoder" title="Adding an Encoder" class="md-nav__link">
    Adding an Encoder
  </a>
  
    <nav class="md-nav">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#1-add-a-new-encoder-class" title="1. Add a new encoder class" class="md-nav__link">
    1. Add a new encoder class
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#2-add-the-new-encoder-class-to-the-corresponding-encoder-registry" title="2. Add the new encoder class to the corresponding encoder registry" class="md-nav__link">
    2. Add the new encoder class to the corresponding encoder registry
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#adding-a-decoder" title="Adding a Decoder" class="md-nav__link">
    Adding a Decoder
  </a>
  
    <nav class="md-nav">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#1-add-a-new-decoder-class" title="1. Add a new decoder class" class="md-nav__link">
    1. Add a new decoder class
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#2-add-the-new-decoder-class-to-the-corresponding-decoder-registry" title="2. Add the new decoder class to the corresponding decoder registry" class="md-nav__link">
    2. Add the new decoder class to the corresponding decoder registry
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#adding-a-new-feature-type" title="Adding a new Feature Type" class="md-nav__link">
    Adding a new Feature Type
  </a>
  
    <nav class="md-nav">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#1-add-a-new-feature-class" title="1. Add a new feature class" class="md-nav__link">
    1. Add a new feature class
  </a>
  
    <nav class="md-nav">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#build_input" title="build_input" class="md-nav__link">
    build_input
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#build_output" title="build_output" class="md-nav__link">
    build_output
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
        
          <li class="md-nav__item">
  <a href="#2-add-the-new-feature-class-to-the-corresponding-feature-registry" title="2. Add the new feature class to the corresponding feature registry" class="md-nav__link">
    2. Add the new feature class to the corresponding feature registry
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#style-guidelines" title="Style Guidelines" class="md-nav__link">
    Style Guidelines
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#tests" title="Tests" class="md-nav__link">
    Tests
  </a>
  
    <nav class="md-nav">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#checklist" title="Checklist" class="md-nav__link">
    Checklist
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#running-tests" title="Running tests" class="md-nav__link">
    Running tests
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#example" title="Example" class="md-nav__link">
    Example
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
      
      
      
      
    </ul>
  
</nav>
    
  </li>

        
        
        
        


  <li class="md-nav__item">
    <a href="../api/" title="API" class="md-nav__link">
      API
    </a>
  </li>

        
        
        
        


  <li class="md-nav__item">
    <a href="../faq/" title="FAQ" class="md-nav__link">
      FAQ
    </a>
  </li>

        
    </ul>
</nav>
                  </div>
                </div>
              </div>
            
            
              <div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    
<nav class="md-nav md-nav--secondary">
  
  
  
    <label class="md-nav__title" for="__toc">Table of contents</label>
    <ul class="md-nav__list" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#codebase-structure" title="Codebase Structure" class="md-nav__link">
    Codebase Structure
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#adding-an-encoder" title="Adding an Encoder" class="md-nav__link">
    Adding an Encoder
  </a>
  
    <nav class="md-nav">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#1-add-a-new-encoder-class" title="1. Add a new encoder class" class="md-nav__link">
    1. Add a new encoder class
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#2-add-the-new-encoder-class-to-the-corresponding-encoder-registry" title="2. Add the new encoder class to the corresponding encoder registry" class="md-nav__link">
    2. Add the new encoder class to the corresponding encoder registry
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#adding-a-decoder" title="Adding a Decoder" class="md-nav__link">
    Adding a Decoder
  </a>
  
    <nav class="md-nav">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#1-add-a-new-decoder-class" title="1. Add a new decoder class" class="md-nav__link">
    1. Add a new decoder class
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#2-add-the-new-decoder-class-to-the-corresponding-decoder-registry" title="2. Add the new decoder class to the corresponding decoder registry" class="md-nav__link">
    2. Add the new decoder class to the corresponding decoder registry
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#adding-a-new-feature-type" title="Adding a new Feature Type" class="md-nav__link">
    Adding a new Feature Type
  </a>
  
    <nav class="md-nav">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#1-add-a-new-feature-class" title="1. Add a new feature class" class="md-nav__link">
    1. Add a new feature class
  </a>
  
    <nav class="md-nav">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#build_input" title="build_input" class="md-nav__link">
    build_input
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#build_output" title="build_output" class="md-nav__link">
    build_output
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
        
          <li class="md-nav__item">
  <a href="#2-add-the-new-feature-class-to-the-corresponding-feature-registry" title="2. Add the new feature class to the corresponding feature registry" class="md-nav__link">
    2. Add the new feature class to the corresponding feature registry
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#style-guidelines" title="Style Guidelines" class="md-nav__link">
    Style Guidelines
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#tests" title="Tests" class="md-nav__link">
    Tests
  </a>
  
    <nav class="md-nav">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#checklist" title="Checklist" class="md-nav__link">
    Checklist
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#running-tests" title="Running tests" class="md-nav__link">
    Running tests
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#example" title="Example" class="md-nav__link">
    Example
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
      
      
      
      
    </ul>
  
</nav>
                  </div>
                </div>
              </div>
            
          
          <div class="md-content">
            <article class="md-content__inner md-typeset">
              
                
                  <a href="https://github.com/uber/ludwig/edit/master/docs/developer_guide.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a>
                
                
                  <h1>Developer Guide</h1>
                
                <h2 id="codebase-structure">Codebase Structure<a class="headerlink" href="#codebase-structure" title="Permanent link">&para;</a></h2>
<p>The codebase is organized in a modular, datatype / feature centric way so that adding a feature for a new datatype is pretty straightforward and requires isolated code changes. All the datatype specific logic lives in the corresponding feature module all of which are under <code>ludwig/features/</code>.</p>
<p>Feature classes contain raw data preprocessing logic specific to each data type. All input (output) features implement <code>build_input</code> (<code>build_output</code>) method which is used to build encodings (decode outputs). Output features also contain datatype-specific logic to compute output measures such as loss, accuracy, etc.</p>
<p>Encoders and decoders are modularized as well (they are under <code>ludwig/models/modules</code>) so that they can be used by multiple features. For example sequence encoders are shared among text, sequence, and timeseries features.</p>
<p>Various model architecture components which can be reused are also split into dedicated modules, for example convolutional modules, fully connected modules, etc.</p>
<p>Bulk of the training logic resides in <code>ludwig/models/model.py</code> which initializes a tensorflow session, feeds the data, and executes training.</p>
<h2 id="adding-an-encoder">Adding an Encoder<a class="headerlink" href="#adding-an-encoder" title="Permanent link">&para;</a></h2>
<h3 id="1-add-a-new-encoder-class">1. Add a new encoder class<a class="headerlink" href="#1-add-a-new-encoder-class" title="Permanent link">&para;</a></h3>
<p>Source code for encoders lives under <code>ludwig/models/modules</code>.
New encoder objects should be defined in the corresponding files, for example all new sequence encoders should be added to <code>ludwig/models/modules/sequence_encoders.py</code>.</p>
<p>All the encoder parameters should be provided as arguments in the constructor with their default values set. For example <code>RNN</code> encoder takes the following list of arguments in its constructor:</p>
<div class="codehilite"><pre><span></span><span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span>
    <span class="bp">self</span><span class="p">,</span>
    <span class="n">should_embed</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
    <span class="n">vocab</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
    <span class="n">representation</span><span class="o">=</span><span class="s1">&#39;dense&#39;</span><span class="p">,</span>
    <span class="n">embedding_size</span><span class="o">=</span><span class="mi">256</span><span class="p">,</span>
    <span class="n">embeddings_trainable</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
    <span class="n">pretrained_embeddings</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
    <span class="n">embeddings_on_cpu</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span>
    <span class="n">num_layers</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
    <span class="n">state_size</span><span class="o">=</span><span class="mi">256</span><span class="p">,</span>
    <span class="n">cell_type</span><span class="o">=</span><span class="s1">&#39;rnn&#39;</span><span class="p">,</span>
    <span class="n">bidirectional</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span>
    <span class="n">dropout</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span>
    <span class="n">initializer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
    <span class="n">regularize</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
    <span class="n">reduce_output</span><span class="o">=</span><span class="s1">&#39;last&#39;</span><span class="p">,</span>
    <span class="o">**</span><span class="n">kwargs</span>
<span class="p">):</span>
</pre></div>


<p>Typically all the dependencies are initialized in the encoder's constructor (in the case of the RNN encoder these are EmbedSequence and RecurrentStack modules) so that at the end of the constructor call all the layers are fully described.</p>
<p>Actual creation of tensorflow variables takes place inside the <code>__call__</code> method of the encoder. All encoders should have the following signature:</p>
<div class="codehilite"><pre><span></span><span class="fm">__call__</span><span class="p">(</span>
    <span class="bp">self</span><span class="p">,</span>
    <span class="n">input_placeholder</span><span class="p">,</span>
    <span class="n">regularizer</span><span class="p">,</span>
    <span class="n">dropout</span><span class="p">,</span>
    <span class="n">is_training</span>
<span class="p">)</span>
</pre></div>


<p><strong>Inputs</strong></p>
<ul>
<li><strong>input_placeholder</strong> (tf.Tensor): input tensor.</li>
<li><strong>regularizer</strong> (A (Tensor -&gt; Tensor or None) function): regularizer function passed to <code>tf.get_variable</code> method.</li>
<li><strong>dropout</strong> (tf.Tensor(dtype: tf.float32)): dropout rate.</li>
<li><strong>is_training</strong> (tf.Tensor(dtype: tf.bool), default: <code>True</code>): boolean indicating whether this is a training dataset.</li>
</ul>
<p><strong>Return</strong></p>
<ul>
<li><strong>hidden</strong> (tf.Tensor(dtype: tf.float32)): feature encodings.</li>
<li><strong>hidden_size</strong> (int): feature encodings size.</li>
</ul>
<p>Encoders are initialized as class member variables in input feature object constructors and called inside <code>build_input</code> methods.</p>
<h3 id="2-add-the-new-encoder-class-to-the-corresponding-encoder-registry">2. Add the new encoder class to the corresponding encoder registry<a class="headerlink" href="#2-add-the-new-encoder-class-to-the-corresponding-encoder-registry" title="Permanent link">&para;</a></h3>
<p>Mapping between encoder keywords in the model definition and encoder classes is done by encoder registries: for example sequence encoder registry is defined in <code>ludwig/features/sequence_feature.py</code></p>
<div class="codehilite"><pre><span></span>sequence_encoder_registry = {
    &#39;stacked_cnn&#39;: StackedCNN,
    &#39;parallel_cnn&#39;: ParallelCNN,
    &#39;stacked_parallel_cnn&#39;: StackedParallelCNN,
    &#39;rnn&#39;: RNN,
    &#39;cnnrnn&#39;: CNNRNN,
    &#39;embed&#39;: EmbedEncoder
}
</pre></div>


<h2 id="adding-a-decoder">Adding a Decoder<a class="headerlink" href="#adding-a-decoder" title="Permanent link">&para;</a></h2>
<h3 id="1-add-a-new-decoder-class">1. Add a new decoder class<a class="headerlink" href="#1-add-a-new-decoder-class" title="Permanent link">&para;</a></h3>
<p>Souce code for decoders lives under <code>ludwig/models/modules</code>.
New decoder objects should be defined in the corresponding files, for example all new sequence decoders should be added to <code>ludwig/models/modules/sequence_decoders.py</code>.</p>
<p>All the decoder parameters should be provided as arguments in the constructor with their default values set. For example <code>Generator</code> decoder takes the following list of arguments in its constructor:</p>
<div class="codehilite"><pre><span></span><span class="fm">__init__</span><span class="p">(</span>
    <span class="bp">self</span><span class="p">,</span>
    <span class="n">cell_type</span><span class="o">=</span><span class="s1">&#39;rnn&#39;</span><span class="p">,</span>
    <span class="n">state_size</span><span class="o">=</span><span class="mi">256</span><span class="p">,</span>
    <span class="n">embedding_size</span><span class="o">=</span><span class="mi">64</span><span class="p">,</span>
    <span class="n">beam_width</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
    <span class="n">num_layers</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
    <span class="n">attention_mechanism</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
    <span class="n">tied_embeddings</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
    <span class="n">initializer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
    <span class="n">regularize</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
    <span class="o">**</span><span class="n">kwargs</span>
<span class="p">)</span>
</pre></div>


<p>Decoders are initialized as class member variables in output feature object constructors and called inside <code>build_output</code> methods.</p>
<h3 id="2-add-the-new-decoder-class-to-the-corresponding-decoder-registry">2. Add the new decoder class to the corresponding decoder registry<a class="headerlink" href="#2-add-the-new-decoder-class-to-the-corresponding-decoder-registry" title="Permanent link">&para;</a></h3>
<p>Mapping between decoder keywords in the model definition and decoder classes is done by decoder registries: for example sequence decoder registry is defined in <code>ludwig/features/sequence_feature.py</code></p>
<div class="codehilite"><pre><span></span><span class="n">sequence_decoder_registry</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s1">&#39;generator&#39;</span><span class="p">:</span> <span class="n">Generator</span><span class="p">,</span>
    <span class="s1">&#39;tagger&#39;</span><span class="p">:</span> <span class="n">Tagger</span>
<span class="p">}</span>
</pre></div>


<h2 id="adding-a-new-feature-type">Adding a new Feature Type<a class="headerlink" href="#adding-a-new-feature-type" title="Permanent link">&para;</a></h2>
<h3 id="1-add-a-new-feature-class">1. Add a new feature class<a class="headerlink" href="#1-add-a-new-feature-class" title="Permanent link">&para;</a></h3>
<p>Souce code for feature classes lives under <code>ludwig/features</code>.
Input and output feature classes are defined in the same file, for example <code>CategoryInputFeature</code> and <code>CategoryOutputFeature</code> are defined in <code>ludwig/features/category_feature.py</code>.</p>
<p>An input features inherit from the <code>InputFeature</code> and corresponding base feature classes, for example <code>CategoryInputFeature</code> inherits from <code>CategoryBaseFeature</code> and <code>InputFeature</code>.</p>
<p>Similarly, output features inherit from the <code>OutputFeature</code> and corresponding base feature classes, for example <code>CategoryOutputFeature</code> inherits from <code>CategoryBaseFeature</code> and <code>OutputFeature</code>.</p>
<p>Feature parameters are provided in a dictionary of key-value pairs as an argument to the input or output feature constructor which contains default parameter values as well.</p>
<p>All input and output features should implement <code>build_input</code> and <code>build_output</code> methods correspondingly with the following signatures:</p>
<h4 id="build_input">build_input<a class="headerlink" href="#build_input" title="Permanent link">&para;</a></h4>
<div class="codehilite"><pre><span></span><span class="n">build_input</span><span class="p">(</span>
    <span class="bp">self</span><span class="p">,</span>
    <span class="n">regularizer</span><span class="p">,</span>
    <span class="n">dropout_rate</span><span class="p">,</span>
    <span class="n">is_training</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span>
    <span class="o">**</span><span class="n">kwargs</span>
<span class="p">)</span>
</pre></div>


<p><strong>Inputs</strong></p>
<ul>
<li><strong>regularizer</strong> (A (Tensor -&gt; Tensor or None) function): regularizer function passed to <code>tf.get_variable</code> method.</li>
<li><strong>dropout_rate</strong> (tf.Tensor(dtype: tf.float32)): dropout rate.</li>
<li><strong>is_training</strong> (tf.Tensor(dtype: tf.bool), default: <code>True</code>): boolean indicating whether this is a training dataset.</li>
</ul>
<p><strong>Return</strong></p>
<ul>
<li><strong>feature_representation</strong> (dict): the following dictionary</li>
</ul>
<div class="codehilite"><pre><span></span><span class="p">{</span>
    <span class="s1">&#39;type&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span><span class="p">,</span> <span class="c1"># str</span>
    <span class="s1">&#39;representation&#39;</span><span class="p">:</span> <span class="n">feature_representation</span><span class="p">,</span> <span class="c1"># tf.Tensor(dtype: tf.float32)</span>
    <span class="s1">&#39;size&#39;</span><span class="p">:</span> <span class="n">feature_representation_size</span><span class="p">,</span> <span class="c1"># int</span>
    <span class="s1">&#39;placeholder&#39;</span><span class="p">:</span> <span class="n">placeholder</span> <span class="c1"># tf.Tensor(dtype: tf.float32)</span>
<span class="p">}</span>
</pre></div>


<h4 id="build_output">build_output<a class="headerlink" href="#build_output" title="Permanent link">&para;</a></h4>
<div class="codehilite"><pre><span></span><span class="n">build_output</span><span class="p">(</span>
    <span class="bp">self</span><span class="p">,</span>
    <span class="n">hidden</span><span class="p">,</span>
    <span class="n">hidden_size</span><span class="p">,</span>
    <span class="n">regularizer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
    <span class="o">**</span><span class="n">kwargs</span>
<span class="p">)</span>
</pre></div>


<p><strong>Inputs</strong></p>
<ul>
<li><strong>hidden</strong> (tf.Tensor(dtype: tf.float32)): output feature representation.</li>
<li><strong>hidden_size</strong> (int): output feature representation size.</li>
<li><strong>regularizer</strong> (A (Tensor -&gt; Tensor or None) function): regularizer function passed to <code>tf.get_variable</code> method.</li>
</ul>
<p><strong>Return</strong>
- <strong>train_mean_loss</strong> (tf.Tensor(dtype: tf.float32)): mean loss for train dataset.
- <strong>eval_loss</strong> (tf.Tensor(dtype: tf.float32)): mean loss for evaluation dataset.
- <strong>output_tensors</strong> (dict): dictionary containing feature specific output tensors (predictions, probabilities, losses, etc).</p>
<h3 id="2-add-the-new-feature-class-to-the-corresponding-feature-registry">2. Add the new feature class to the corresponding feature registry<a class="headerlink" href="#2-add-the-new-feature-class-to-the-corresponding-feature-registry" title="Permanent link">&para;</a></h3>
<p>Input and output feature registries are defined in <code>ludwig/features/feature_registries.py</code>.</p>
<h2 id="style-guidelines">Style Guidelines<a class="headerlink" href="#style-guidelines" title="Permanent link">&para;</a></h2>
<p>We expect contributions to mimic existing patterns in the codebase and demonstrate good practices: the code should be concise, readable, PEP8-compliant, and conforming to 80 character line length limit.</p>
<h2 id="tests">Tests<a class="headerlink" href="#tests" title="Permanent link">&para;</a></h2>
<p>We are using <code>pytest</code> to run tests. 
Current test coverage is limited to several integration tests which ensure end-to-end functionality but we are planning to expand it.</p>
<h3 id="checklist">Checklist<a class="headerlink" href="#checklist" title="Permanent link">&para;</a></h3>
<p>Before running tests, make sure 
1. Your environment is properly setup.
2. You build the latest code by running <code>python setup.py install</code> from the Ludwig root directory.
3. You have write access on the machine. Some of the tests require saving data to disk.</p>
<h3 id="running-tests">Running tests<a class="headerlink" href="#running-tests" title="Permanent link">&para;</a></h3>
<p>To run all tests, just run
<code>pytest</code> from the ludwig root directory.</p>
<p>To run a single test, run</p>
<div class="codehilite"><pre><span></span>pytest path_to_filename::test_method_name
</pre></div>


<h3 id="example">Example<a class="headerlink" href="#example" title="Permanent link">&para;</a></h3>
<div class="codehilite"><pre><span></span>pytest tests/integration_tests/test_experiment.py::test_visual_question_answering
</pre></div>
                
                  
                
              
              
                


              
            </article>
          </div>
        </div>
      </main>
      
        

<!-- Application footer -->
<footer class="md-footer">

    <!-- Link to previous and/or next page -->
    
    <div class="md-footer-nav">
        <nav class="md-footer-nav__inner md-grid">

            <!-- Link to previous page -->
            
            <a class="md-flex md-footer-nav__link md-footer-nav__link--prev"
               href="../user_guide/"
               rel="prev"
               title="User Guide">
                <div class="md-flex__cell md-flex__cell--shrink">
                    <i class="md-icon md-icon--arrow-back
                    md-footer-nav__button"></i>
                </div>
                <div class="md-flex__cell md-flex__cell--stretch
                  md-footer-nav__title">
              <span class="md-flex__ellipsis">
                <span class="md-footer-nav__direction">
                  Previous
                </span>
                User Guide
              </span>
                </div>
            </a>
            

            <!-- Link to next page -->
            
            <a class="md-flex md-footer-nav__link md-footer-nav__link--next"
               href="../api/"
               rel="next"
               title="API">
                <div class="md-flex__cell md-flex__cell--stretch
                  md-footer-nav__title">
              <span class="md-flex__ellipsis">
                <span class="md-footer-nav__direction">
                  Next
                </span>
                API
              </span>
                </div>
                <div class="md-flex__cell md-flex__cell--shrink">
                    <i class="md-icon md-icon--arrow-forward
                    md-footer-nav__button"></i>
                </div>
            </a>
            
        </nav>
    </div>
    

    <!-- Further information -->
    <div class="md-footer-meta md-typeset">
        <div class="md-footer-meta__inner md-grid">

            <!-- Copyright and theme information -->
            <div class="md-footer-copyright">
                <div class="footer-logo-smallpad"></div>
                
                <div class="md-footer-copyright__highlight">
                    Copyright &copy; 2018 - 2019 Uber Technologies Inc.
                </div>
                
                Website by <a href="http://w4nderlu.st">w4nderlust</a> powered by
                <a href="https://www.mkdocs.org">MkDocs</a>,
                <a href="https://squidfunk.github.io/mkdocs-material/">Material for MkDocs</a>,
                <a href="http://www.styleshout.com/">styleshout</a> and
                <a href="http://cables.gl/">cables</a>.
            </div>

            <!-- Social links -->
            
            
            
        </div>
    </div>
</footer>
      
    </div>

    <script src="../assets/javascripts/application.a353778b.js"></script>
      
      <script>app.initialize({version:"1.0.4",url:{base:".."}})</script>


    </body>
</html>